home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Scene Storm
/
Scene Storm - Volume 1.iso
/
coding
/
asm
/
utils
/
finnslator
/
finnslator.asm
next >
Wrap
Assembly Source File
|
1980-01-03
|
7KB
|
275 lines
;+asm
;do
;*
;
; ### Finnslator.library by JM v 1.4 ###
;
; - Created 901024 by JM -
;
;
; Bugs: Doesn't split the input string at word boundary on buffer full
; conditions.
;
;
; Edited:
;
; - 901024 by JM -> v0.01 - basics written (see sample.library.asm).
; - 901025 by JM -> v1.00 - it works now. lots of room for
; improvements, though.
; - 901026 by JM -> v1.1 - now special commands are processed
; before alphabets.
; - 901029 by JM -> v1.2 - destination buffer full condition now
; detected.
; - ` now acts as an escape character.
; - returns error code in d0.
; - 901029 by JM -> v1.3 - compatibility with original Translate()
; improved.
; - 901029 by JM -> v1.4 - still some fixes. de-alping.
;
;
VERSION EQU 1
REVISION EQU 4
SPEC macro * <orig_char>,<dest_string>
dc.b SPEC2\@-SPEC1\@
dc.b \1
SPEC1\@ dc.b \2
SPEC2\@
endm
include "exec/types.i"
include "exec/initializers.i"
include "exec/libraries.i"
include "exec/lists.i"
include "exec/alerts.i"
include "exec/resident.i"
include "libraries/dos.i"
include "finnslatorbase.i"
begin moveq #-1,d0 ; if somebody runs us...
rts
ROMTag dc.w RTC_MATCHWORD ; UWORD RT_MATCHWORD
dc.l ROMTag ; APTR RT_MATCHTAG
dc.l EndOfLib ; APTR RT_ENDSKIP
dc.b RTF_AUTOINIT ; UBYTE RT_FLAGS
dc.b VERSION ; UBYTE RT_VERSION
dc.b NT_LIBRARY ; UBYTE RT_TYPE
dc.b 0 ; BYTE RT_PRI
dc.l LibName ; APTR RT_NAME
dc.l LibId ; APTR RT_IDSTRING
dc.l InitStuff ; APTR RT_INIT
LibName FINNSLATORNAME
LibId dc.b 'finnslator 1.4 (29 Oct 1990)',13,10,0
ds.w 0
InitStuff dc.l FinnslatorBase_SIZEOF ; size of library base
dc.l Functions ; pointer to function table
dc.l LibBaseData ; pointer to lib base data
dc.l InitRoutine ; ptr to initializing routine
Functions dc.l r_Open ; library Open call
dc.l r_Close ; library Close call
dc.l r_Expunge ; library Expunge call
dc.l r_Null ; reserved for Exec
dc.l r_Translate ; Translate call
dc.l -1 ; end marker
LibBaseData INITBYTE LN_TYPE,NT_LIBRARY
INITLONG LN_NAME,LibName
INITBYTE LIB_FLAGS,LIBF_SUMUSED!LIBF_CHANGED
INITWORD LIB_VERSION,VERSION
INITWORD LIB_REVISION,REVISION
INITLONG LIB_IDSTRING,LibId
dc.l 0
InitRoutine move.l a5,-(sp) ; save a5
move.l d0,a5 ; library base into a5
move.l a6,finsb_SysLib(a5) ; save ExecBase into LibBase
move.l a0,finsb_SegList(a5) ; save SegList pointer
; additional initializing would be done here
move.l a5,d0 ; lib base back to d0
move.l (sp)+,a5 ; restore a5
rts
r_Open addq.w #1,LIB_OPENCNT(a6) ; one more user
bclr #LIBB_DELEXP,finsb_Flags(a6) ; so expunge impossible
move.l a6,d0 ; return library base in d0
rts
r_Close moveq #0,d0 ; return value
subq.w #1,LIB_OPENCNT(a6) ; one user less
bne.s 1$ ; last user?
btst #LIBB_DELEXP,finsb_Flags(a6) ; delayed Expunge?
beq.s 1$
bsr r_Expunge ; yes, do it
1$ rts ; if other users, just return
r_Expunge movem.l d2/a5-a6,-(sp)
move.l a6,a5 ; library base pointer
move.l finsb_SysLib(a5),a6 ; ExecBase
tst.w LIB_OPENCNT(a5) ; are we still open?
beq.s 1$
bset #LIBB_DELEXP,finsb_Flags(a5) ; yes, delayed Expunge
moveq #0,d0 ; and return a zero
movem.l (sp)+,d2/a5-a6
rts
1$ move.l finsb_SegList(a5),d2 ; SegList* to d2
move.l a5,a1
xref _LVORemove ; remove from library list
jsr _LVORemove(a6)
; other cleanup operations would be done here
moveq #0,d0
move.l a5,a1 ; library base
move.w LIB_NEGSIZE(a5),d0 ; get size below the base
sub.l d0,a1 ; get pointer to mem block
add.w LIB_POSSIZE(a5),d0 ; add size after the base
xref _LVOFreeMem ; free memory used by lib
jsr _LVOFreeMem(a6)
move.l d2,d0 ; return SegList pointer
movem.l (sp)+,d2/a5-a6
rts
r_Null moveq #0,d0 ; Exec reserved routine
rts
******* Actual library routine(s) begin here: *******
; error = Translate(input,length,output,bufsiz);
;
; inputs:
; a0 = input string (may be NULL terminated)
; d0 = length of input string
; a1 = output buffer
; d1 = size of output buffer
; internal variables:
; a0 = source pointer
; a1 = destination pointer
; d0 = characters left in source buffer
; d1 = number of free bytes in destination buffer
; d2 = temporary (character being processed)
; d3 = temporary for table search
; d4 = storage for input length
; outputs:
; d0 = NULL (no error) or -N where N is index to first char in input
; buffer that was not processed
;
r_Translate movem.l d2-d4/a2,-(sp)
move.l d0,d4 ; length of input string
subq.l #1,d1 ; space for NULL char
ble.s exitnow ; no space in buffer at all
bra.s loop
reploop subq.l #1,d0 ; one char less
loop tst.l d0 ; characters left?
beq.s endofit ; none -> exit
moveq #0,d2 ; clear d2
move.b (a0)+,d2 ; get one char
beq.s endofit ; NULL -> exit
cmp.b #96,d2 ; is it a ` ?
bne.s 10$
subq.l #1,d1
bmi.s endofit ; end of destination buffer
subq.l #1,d0
beq.s endofit ; end of source string
move.b (a0)+,(a1)+ ; copy one char literally
bra.s reploop
10$ cmp.b #'a',d2 ; convert to UPPER CASE
bcs.s 1$
cmp.b #'z',d2
bhi.s 1$
sub.b #32,d2
1$ cmp.b #224,d2 ; convert special chars also
bcs.s 2$
sub.b #32,d2
2$ bsr dospecials
tst.l d1
bmi.s endofit
cmp.b #'A',d2 ; is it an alphabet?
bcs.s reploop
cmp.b #'Z',d2
bhi.s reploop
sub.b #'A',d2 ; yes -> A->0; Z->25
lea alphatable(pc),a2 ; convert into phonemes
add.w d2,a2
add.w d2,a2 ; address in table
subq.l #1,d1
bmi.s endofit ; destination buffer overflow
move.b (a2)+,d2 ; get 1 or 2 bytes from table
beq.s 100$
subq.l #1,d1
bmi.s endofit ; destination buffer overflow
move.b d2,(a1)+
100$ move.b (a2)+,(a1)+ ; copy bytes into buffer
subq.l #1,d0 ; one char processed
bra.s loop
endofit clr.b (a1) ; NULL terminate string
exitnow tst.l d0
beq.s 101$
sub.l d4,d0 ; -(idx to next char) or NULL
101$ movem.l (sp)+,d2-d4/a2
rts
dospecials lea othertable(pc),a2
moveq #0,d3
dospecloop add.w d3,a2 ; skip to next entry
move.b (a2)+,d3 ; get size of entry
beq.s dosendeth ; NULL = end of table
cmp.b (a2)+,d2 ; compare with this entry
bne.s dospecloop ; if not equal, try next
sub.l d3,d1 ; right entry found:
bge.s dospecbufok ; enough room in buffer?
moveq #-1,d1 ; nope -> d1=-1; return
rts
dospeccopy move.b (a2)+,(a1)+ ; copy string
dospecbufok dbf d3,dospeccopy
moveq #0,d2 ; return NULL
dosendeth rts
alphatable dc.w 'AH','B','S','D','EH','F','G'
dc.w '/H','IH','Y','K','L','M','N'
dc.w 'OH','P','KV','R','S','T','UH'
dc.w 'V','W','KS','IX','TS'
othertable SPEC 32,32 ; SPC
SPEC 13,32 ; CR -> SPC
SPEC '.','.'
SPEC 44,44 ; ,
SPEC '?','?'
SPEC '(','('
SPEC ')',')'
SPEC '-','-'
SPEC 'I','IHIH' ; I
SPEC 196,'AE'
SPEC 214,'ER'
SPEC 197,'OH'
SPEC 209,'NX' ; äng
SPEC 182,'PIHIHIHIHAH'
SPEC '*','TAE/HTIH'
SPEC '0','NOHLLAH'
SPEC '1','IXKSIH'
SPEC '2','KAHKSIH'
SPEC '3','KOHLMEH'
SPEC '4','NEHLYAE'
SPEC '5','VIHIHIHIHSIH'
SPEC '6','KUHUHSIH'
SPEC '7','SEHIHTSEHMAEN'
SPEC '8','KAH/HDEHKSAHN'
SPEC '9','IXIX/HDEHKSAEN'
dc.b 0
ds.w 0
***********************************************************************
EndOfLib end